from django.db import transaction
from rest_framework import serializers

from celery_tasks.detail_html.task import get_detail_html

from goods.models import SKU, SKUSpecification, GoodsCategory, SPUSpecification, SpecificationOption


# SKU规格表序列化器
class SKUSpecificationSerialzier(serializers.ModelSerializer):

    spec_id = serializers.IntegerField()
    option_id = serializers.IntegerField()

    class Meta:
        model = SKUSpecification
        fields = ('spec_id','option_id')

#获取sku表信息的序列化器
class SKUGoodsSerializer(serializers.ModelSerializer):
    # 指定所关联选项信息，关联嵌套返回
    specs = SKUSpecificationSerialzier(many=True)
    # 指定分类信息
    category_id = serializers.IntegerField()
    # 关联嵌套返回
    category = serializers.StringRelatedField(read_only=True)
    # 指定所关联的spu的信息
    spu_id = serializers.IntegerField()
    # 关联嵌套返回
    spu = serializers.StringRelatedField(read_only=True)

    class Meta:
        model = SKU# SKU表中category外键关联了分类表。spu外键关联了SPU商品表
        fields = '__all__'
    # 保存商品
    def  create(self,validate_data):
        specs = validate_data['specs']
        # specs = self.context['request'].data.get('specs')
        del validate_data['specs']

        with transaction.atomic():
            # 开启事务
            save_point = transaction.savepoint()
            try:
                # 1、保存sku表
                sku = SKU.objects.create(**validate_data)
                # 2、保存SKU具体规格
                for spec in specs:
                    SKUSpecification.objects.create(sku=sku, spec_id=spec['spec_id'], option_id=spec['option_id'])
            except Exception as e :
                # 捕获异常，说明数据库操作失败，进行回滚
                transaction.savepoint_rollback(save_point)
                return serializers.ValidationError(e)
            else:
                transaction.savepoint_commit(save_point)

                # 执行异步任务生成新的静态页面
                get_detail_html.delay(sku.id)
                return sku
    # 修改商品
    def update(self,instance,validate_data):
        with transaction.atomic():
            save_point = transaction.savepoint()
            try:
                # 1、更新sku表
                specs = validate_data['specs']
                del validate_data['specs']
                SKU.objects.filter(id = instance.id).update(**validate_data)
                for spec in specs:
                    # 2、更新SKU具体规格表
                    # SKUSpecification.objects.create(sku=instance,spec_id=spec['spec_id'],option_id = spec['option_id'])
                    SKUSpecification.objects.filter(sku=instance,spec=spec['spec_id']).update(option_id = spec['option_id'])

            except Exception as e :
                # 捕获异常，说明数据库操作失败，进行回滚
                transaction.savepoint_rollback(save_point)
                return serializers.ValidationError(e)
            else:
                # 执行异步任务生成新的静态页面
                transaction.savepoint_commit(save_point)
                get_detail_html.delay(instance.id)
                return instance


# 商品类别
class GoodsCategorySerializer(serializers.ModelSerializer):

    class Meta:
        model = GoodsCategory
        fields = ('id','name')


# 商品规格选项表
class SpecificationOptionSerializer(serializers.ModelSerializer):
    class Meta:
        model = SpecificationOption
        fields = ('id','value')


# 商品SPU规格
class SPUSpecificationSerializer(serializers.ModelSerializer):

    # 关联指定信息，嵌套返回
    options =  SpecificationOptionSerializer(read_only=True,many=True)
    spu = serializers.StringRelatedField(read_only=True)
    spu_id = serializers.IntegerField(read_only=True)


    class Meta:
        model = SPUSpecification
        fields = ('id','name','spu','spu_id','options')




